#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>

static int send_interval = 1000;

void send_packets(pcap_t *handle, const char *file_path) {
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_t *file_handle;
  struct pcap_pkthdr *header;
  const u_char *packet;
  int res;

  file_handle = pcap_open_offline(file_path, errbuf);
  if (file_handle == NULL) {
    fprintf(stderr, "Couldn't open file %s: %s\n", file_path, errbuf);
    return;
  }

  // 读取并发送数据包
  while ((res = pcap_next_ex(file_handle, &header, &packet)) >= 0) {
    if (res == 0)
      continue; // 超时
    if (pcap_sendpacket(handle, packet, header->len) != 0) {
      fprintf(stderr, "Error sending packet: %s\n", pcap_geterr(handle));
    }
    usleep(send_interval);
  }

  pcap_close(file_handle);
}

void process_directory(pcap_t *handle, const char *directory) {
  DIR *dir;
  struct dirent *entry;
  char file_path[256];

  dir = opendir(directory);
  if (dir == NULL) {
    perror("opendir");
    exit(EXIT_FAILURE);
  }

  while ((entry = readdir(dir)) != NULL) {
    if (entry->d_type == DT_REG) { // 只处理常规文件
      snprintf(file_path, sizeof(file_path), "%s/%s", directory, entry->d_name);
      printf("Processing file: %s\n", file_path);
      send_packets(handle, file_path);
    }
  }

  closedir(dir);
}

int main(int argc, char *argv[]) {
  char *interface = NULL;
  char *directory = NULL;
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_t *handle;
  int opt;

  // 解析命令行参数
  while ((opt = getopt(argc, argv, "i:d:t:")) != -1) {
    switch (opt) {
    case 'i':
      interface = optarg;
      break;
    case 'd':
      directory = optarg;
      break;
    case 't':
      send_interval = atoi(optarg);
      break;
    default:
      fprintf(stderr, "Usage: %s -i interface -d directory\n", argv[0]);
      exit(EXIT_FAILURE);
    }
  }

  if (interface == NULL || directory == NULL) {
    fprintf(stderr, "Interface and directory must be specified.\n");
    exit(EXIT_FAILURE);
  }

  // 打开网卡以发送数据包
  handle = pcap_open_live(interface, BUFSIZ, 1, 1000, errbuf);
  if (handle == NULL) {
    fprintf(stderr, "Couldn't open device %s: %s\n", interface, errbuf);
    exit(EXIT_FAILURE);
  }

  // 处理指定目录中的所有数据包文件
  process_directory(handle, directory);

  pcap_close(handle);
  return 0;
}

